package com.snow.jvm;

/**
 * @类名称：JVM第二节
 * @类描述：
 * @author: bingHeng
 * @Date 2019.04.14
 * @Version: 1.0
*/
public class MyStackDemo {

    /**
     * 栈：也叫栈内存，主管Java程序的运行，是在线程创建时创建，它的生命周期是跟随线程的生命周期，线程结束栈内存也就释放，对于栈来说不存在垃圾回收问题。
     * 只要线程一结束该栈就Over，生命周期和线程一致，是线程私有的。基本类型的变量、实例方法、引用类型的变量都是在函数的栈内存中分配。
     *
     * Exception in thread "main" java.lang.StackOverflowError
     */

    public static void main(String[] args) {
        sayHello();
    }

    public static void sayHello() {
        sayHello();
    }

    /**
     * java.lang.StackOverflowError
     * 以上程序是死循环递归调用，控制台抛出了：java.lang.StackOverflowError异常。
     *
     */

    /**
     * 方法区：方法区是线程共享的，通常用来保存装载的类的元结构信息。
     * 比如：运行时常量池+静态变量+常量+字段+方法字节码+在类\实例\接口中初始化用到的特殊方法等。
     *
     * 通常和永久区关联在一起（Java 7之前），但具体的根JVM的实现和版本有关系。
     */

    /**
     * Heap堆（Java 7之前）
     *  一个JVm实例只存在一个堆内存，堆内存的大小是可以调节的。类加载器读取了类文件后，需要把类、方法、常变量放到堆内存中，保存所有引用类型的真实信息，以方便执行器执行。
     *  堆内存逻辑上分为：新生区、养老区、永久区
     *  新生区：伊甸区（Eden Space）、幸存0区（Survivor 0 Space）、幸存1区（Survivor 1 Space）
     *  逻辑上永久区是和新生区、养老区一块的，但是实际上而言，永久区就称为非堆内存。
     *
     *  新生区：
     *  新生区是类的诞生、成长、消亡的区域，一个类在这里产生、应用，最后被垃圾回收器收集，结束生命。新生区又分为两部分：伊甸区（Eden Space）和幸存者区（Survivor Space），所有的
     *  类都是在伊甸区（Eden Space）被new出来的。
     *  幸存者区（Survivor Space）有两个：幸存0区（Survivor 0 Space）、幸存1区（Survivor 1 Space）。当伊甸区（Eden Space）的空间用完时，程序又需要创建新对象，JVM的垃圾回收器将
     *  对伊甸区（Eden Space）进行垃圾回收（Minor GC），将伊甸区（Eden Space）中的不再被其他对象所引用的对象进行销毁。然后将伊甸区（Eden Space）中的剩余对象移动到幸存0区（Survivor 0 Space），
     *  若幸存0区（Survivor 0 Space）也满了，再对该区进行垃圾回收，然后移动到幸存1区（Survivor 1 Space）。那如果幸存1区（Survivor 1 Space）也满了呢？再移动到养老区。若养老区也满了，那么这个时候将
     *  产生Ma_jorGC(FullGC),进行养老区的内存清理。若养老区执行了Full GC 之后发现依然无法进行对象的保存，就会产生OOM异常，"OutOfMemoryError"。
     *
     *  如果出现：java.lang.OutOfMemoryError:java heap space异常，说明Java虚拟机的堆内存不够，原因有二：
     *  1. Java虚拟机的堆内存设置不够，可以通过参数-Xms、-Xmx来调整
     *  2. 代码中创建了大量大对象，并且长时间不能被垃圾收集器收集（存在被引用）
     *
     *
     *  Java 8之后将最初的永久带取消了，由元空间取代。
     *
     *  堆内存调优简介：
     *  -Xms：设置初始分配大小，默认为物理内存的 "1/64"
     *  -Xmx: 最大分配内存，默认为物理内存的 "1/4"
     *  -XX:+PrintGCDetails: 输出详细的GC处理日志
     *
     */
}
